package net.zoneland.data.dataprofiling.system.service.impl;

import net.zoneland.data.dataprofiling.common.domain.Tree;
import net.zoneland.data.dataprofiling.common.utils.BuildTree;
import net.zoneland.data.dataprofiling.system.domain.MenuEntity;
import net.zoneland.data.dataprofiling.system.domain.RoleEntity;
import net.zoneland.data.dataprofiling.system.domain.UserEntity;
import net.zoneland.data.dataprofiling.system.repository.MenuRepository;
import net.zoneland.data.dataprofiling.system.repository.RoleRepository;
import net.zoneland.data.dataprofiling.system.repository.UserRepository;
import net.zoneland.data.dataprofiling.system.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@Transactional(readOnly = true,rollbackFor = Exception.class)
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuRepository menuRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private UserRepository  userRepository;

    @Cacheable
    @Override
    public Tree<MenuEntity> getSysMenuTreeByuserid(Long userId) {
        UserEntity userEntity = userRepository.getOne(userId);
        List<RoleEntity> roleEntities = userEntity.getRoles();
        List<Tree<MenuEntity>> trees = new ArrayList<>();
        for(RoleEntity roleEntity:roleEntities){
            for(MenuEntity menuEntity:roleEntity.getMenus()){
                Tree<MenuEntity> tree = new Tree<>();
                tree.setId(menuEntity.getMenuId().toString());
                tree.setParentId(menuEntity.getParentMenu().getMenuId().toString());
                tree.setText(menuEntity.getName());
                Map<String, Object> attributes = new HashMap<>(16);
                attributes.put("url", menuEntity.getUrl());
                attributes.put("icon", menuEntity.getIcon());
                tree.setAttributes(attributes);
                trees.add(tree);
            }
        }
        Tree<MenuEntity> t = BuildTree.build(trees);
        return t;
    }

    @Override
    public List<Tree<MenuEntity>> listMenuTree(Long id) {
        UserEntity userEntity = userRepository.getOne(id);
        List<RoleEntity> roleEntities = userEntity.getRoles();
        List<Tree<MenuEntity>> trees = new ArrayList<>();
        for(RoleEntity roleEntity:roleEntities){
            for(MenuEntity menuEntity:roleEntity.getMenus()){
                Tree<MenuEntity> tree = new Tree<>();
                tree.setId(menuEntity.getMenuId().toString());
                tree.setParentId(menuEntity.getParentMenu().getMenuId().toString());
                tree.setText(menuEntity.getName());
                Map<String, Object> attributes = new HashMap<>(16);
                attributes.put("url", menuEntity.getUrl());
                attributes.put("icon", menuEntity.getIcon());
                tree.setAttributes(attributes);
                trees.add(tree);
            }
        }
        List<Tree<MenuEntity>> t = BuildTree.buildList(trees,"0");
        return t;
    }

    @Override
    public Tree<MenuEntity> getTree() {
        List<Tree<MenuEntity>> trees = new ArrayList<Tree<MenuEntity>>();
        List<MenuEntity> menuDOs = list();
        for (MenuEntity sysMenuDO : menuDOs) {
            Tree<MenuEntity> tree = new Tree<MenuEntity>();
            tree.setId(sysMenuDO.getMenuId().toString());
            tree.setParentId(sysMenuDO.getParentMenu().getMenuId().toString());
            tree.setText(sysMenuDO.getName());
            trees.add(tree);
        }
        // 默认顶级菜单为０，根据数据库实际情况调整
        Tree<MenuEntity> t = BuildTree.build(trees);
        return t;
    }

    @Override
    public Tree<MenuEntity> getTree(Long id) {
        List<MenuEntity> menus = list();
        RoleEntity roleEntity = roleRepository.getOne(id);
        List<MenuEntity> tempMenus = new ArrayList<MenuEntity>(roleEntity.getMenus());
        for(MenuEntity m:menus){
            if(tempMenus.contains(m.getParentMenu())){
                tempMenus.remove(m.getParentMenu());
            }
        }

        List<MenuEntity> menuDOs = list();
        List<Tree<MenuEntity>> trees = new ArrayList<Tree<MenuEntity>>();
        for (MenuEntity sysMenuDO : menuDOs) {
            Tree<MenuEntity> tree = new Tree<MenuEntity>();
            tree.setId(sysMenuDO.getMenuId().toString());
            tree.setParentId(sysMenuDO.getParentMenu().getMenuId().toString());
            tree.setText(sysMenuDO.getName());
            Map<String, Object> state = new HashMap<>(16);
            if(tempMenus.contains(sysMenuDO)){
                state.put("selected",true);
            }else {
                state.put("selected",false);
            }
            trees.add(tree);
        }
        // 默认顶级菜单为０，根据数据库实际情况调整
        Tree<MenuEntity> t = BuildTree.build(trees);
        return t;

    }

    @Override
    public List<MenuEntity> list() {
        Sort sort = Sort.by(new Sort.Order(Sort.Direction.ASC,"orderNum"));
        List<MenuEntity> menuEntityList  = menuRepository.findAll(sort);
        return menuEntityList;
    }

    @Transactional(readOnly = false,rollbackFor = Exception.class)
    @Override
    public int remove(Long id) {
        menuRepository.deleteById(id);
        return 1;
    }

    @Transactional(readOnly = false,rollbackFor = Exception.class)
    @Override
    public int save(MenuEntity menu) {
        MenuEntity menuEntity = menuRepository.save(menu);
        if(menuEntity!=null){
            return 1;
        }else {
            return 0;
        }
    }

    @Transactional(readOnly = false,rollbackFor = Exception.class)
    @Override
    public int update(MenuEntity menu) {
        MenuEntity menuEntity = menuRepository.saveAndFlush(menu);
        if(menuEntity!=null){
            return 1;
        }else {
            return 0;
        }
    }

    @Override
    public MenuEntity get(Long id) {
       return menuRepository.getOne(id);
    }

    @Override
    public Set<String> listPerms(Long userId) {
        Set<String> perms = new HashSet<String>();
        UserEntity userEntity = userRepository.getOne(userId);
        List<RoleEntity> roleEntities = userEntity.getRoles();
        for(RoleEntity roleEntity:roleEntities) {
            for (MenuEntity menuEntity : roleEntity.getMenus()) {
                perms.add(menuEntity.getName());
            }
        }
        return perms;
    }
}
